package interfaceGrafica;

import java.awt.Color;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.io.IOException;
import java.util.LinkedList;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.Border;

import dominioProblema.Pedra;

public class PainelAreaJogo extends JPanel implements DropTargetListener {
	
	protected static final long serialVersionUID = 1L;
	protected InterfaceGrafica iG;
	protected ImageIcon iconePeca;
	
	protected int pecaX;
	protected int pecaY;
	protected int pecaLargura;
	protected int pecaAltura;
	
	protected int posicaoX;
	protected int posicaoY;

	protected int pecaCimaX;
	protected int pecaCimaY;
	protected int pecaBaixoX;
	protected int pecaBaixoY;
	protected int pecaDireitaX;
	protected int pecaDireitaY;
	protected int pecaEsquerdaX;
	protected int pecaEsquerdaY;
	
	protected int ponta;
	protected LinkedList<Pedra> disposPedras;
	protected LinkedList<Pedra> ptaC;
	protected LinkedList<Pedra> ptaD;
	
	protected boolean primeiraJogada;
	protected JLabel jLabelMovimento;
	protected JLabel jLabelAtual;

	public PainelAreaJogo(InterfaceGrafica interfaceGrafica) {
    	new DropTarget(this, this);
    	this.iG = interfaceGrafica;
    	this.ponta = 1;
    	setLayout(null);
    	jLabelMovimento = new JLabel();
    	add(jLabelMovimento);
    	primeiraJogada = true;
    	this.disposPedras = new LinkedList<Pedra>();
    	this.ptaC = new LinkedList<Pedra>();
		this.ptaD = new LinkedList<Pedra>();
    }

    public void atualizarDisposicao(LinkedList<Pedra> disposPedras, LinkedList<Pedra> ptaC, LinkedList<Pedra> ptaD, int ponta) {
    	this.ponta = ponta;
    	switch (ponta){
		case 1:
			posicionarPeca(disposPedras.getFirst());
			break;
		case 2:
			posicionarPeca(disposPedras.getLast());
			break;
		case 3:
			posicionarPeca(ptaC.getLast());
			break;
		case 4:
			posicionarPeca(ptaD.getLast());
    	}
    	this.disposPedras = disposPedras;
    	this.ptaC = ptaC;
    	this.ptaD = ptaD;
    }

	public void dragEnter(DropTargetDragEvent evt) {
    	try {
    		Transferable transferable = evt.getTransferable();
    		if (transferable.isDataFlavorSupported(DataFlavor.stringFlavor)) {
    			evt.acceptDrag(DnDConstants.ACTION_MOVE);
    			String valorPeca = (String) transferable.getTransferData(DataFlavor.stringFlavor);
    			iconePeca = new ImageIcon(getClass().getResource("/imagens/" + valorPeca + ".png"));
    			jLabelMovimento.setIcon(iconePeca);
    			jLabelMovimento.setVisible(true);
    			repaint();
    		} else {
    			evt.rejectDrag();
    		}

    	} catch (IOException e) {
    		evt.rejectDrag();
    	} catch (UnsupportedFlavorException e) {
    		evt.rejectDrag();
    	}
    }

    public void dragOver(DropTargetDragEvent evt) {
    	Point point = evt.getLocation();
    	posicaoX = point.x;
    	posicaoY = point.y;
    	Border border;
    	if(primeiraJogada) {
    		border = BorderFactory.createLineBorder(Color.GREEN, 1);
    	} else if((retorneMin(pecaCimaX) <= posicaoX && posicaoX <= retorneMax(pecaCimaX)) && (posicaoY<1400)) {
    		this.ponta = 3;
    		border = BorderFactory.createLineBorder(Color.GREEN, 1);
    	} else if((retorneMin(pecaBaixoX) <= posicaoX && posicaoX <= retorneMax(pecaBaixoX)) && (posicaoY>1600)) {
    		this.ponta = 4;
    		border = BorderFactory.createLineBorder(Color.GREEN, 1);
    	} else if((posicaoX>1550) && (retorneMin(pecaDireitaY) <= posicaoY && posicaoY <= retorneMax(pecaDireitaY))) {
    		this.ponta = 2;
    		border = BorderFactory.createLineBorder(Color.GREEN, 1);
    	} else if((posicaoX<1499) && (retorneMin(pecaEsquerdaY) <= posicaoY && posicaoY <= retorneMax(pecaEsquerdaY))) {
    		this.ponta = 1;
    		border = BorderFactory.createLineBorder(Color.GREEN, 1);
    	} else {
    		this.ponta = 1;
    		border = BorderFactory.createLineBorder(Color.RED, 1);
    	}
    	jLabelMovimento.setBorder(border);
    	jLabelMovimento.setBounds(new Rectangle(posicaoX, posicaoY, 50, 100));
		repaint();
    }
    
    private int retorneMin(int peca) {
		return peca - 10;
    }
    
    private int retorneMax(int peca) {
    	return peca + 60;
    }

    public void dragExit(DropTargetEvent evt) {
    	jLabelMovimento.setVisible(false);
    }

    public void drop(DropTargetDropEvent evt) {
    	jLabelMovimento.setVisible(false);
    	try {
    		Transferable transferable = evt.getTransferable();
    		Pedra pedra = (Pedra) transferable.getTransferData(TransferidorPedra.pedraFlavor);
    		if (transferable.isDataFlavorSupported(TransferidorPedra.pedraFlavor)) {
    			evt.acceptDrop(DnDConstants.ACTION_MOVE);
    			evt.getDropTargetContext().dropComplete(true);
    			if(this.disposPedras.isEmpty())
    				this.disposPedras.addFirst(pedra);
    			posicionarPeca(pedra);
    			iG.informarPecaJogada(pedra, this.ponta);
    		} else {
    			evt.rejectDrop();
    		}

    	} catch (IOException e) {
    		evt.rejectDrop();
    	} catch (UnsupportedFlavorException e) {
    		evt.rejectDrop();
    	}
    }

	private void posicionarPeca(Pedra pedra) {
    	int pa = pedra.getLadoA();
		int pb = pedra.getLadoB();
    	String valorPeca = pedra.getPeca();
    	ImageIcon imagemPeca = null;
		if(primeiraJogada) {
			pecaX = 1500;
			pecaCimaX = 1500;
	    	pecaCimaY = 1375;
	    	pecaBaixoX = 1500;
	    	pecaBaixoY = 1575;
			if(pedra.isDouble()) {
				imagemPeca = new ImageIcon(getClass().getResource("/imagens/" + valorPeca + ".png"));
				pecaY = 1475;
				pecaDireitaX = 1550;
				pecaDireitaY = 1500;
				pecaEsquerdaX = 1400;
				pecaEsquerdaY = 1500;
				pecaLargura = 50;
				pecaAltura = 100;
			}
			else {
				imagemPeca = new ImageIcon(getClass().getResource("/imagensd/" + valorPeca + "d.png"));
				pecaY = 1500;
				pecaDireitaX = 1600;
		    	pecaDireitaY = 1500;
		    	pecaEsquerdaX = 1400;
		    	pecaEsquerdaY = 1500;
				pecaLargura = 100;
				pecaAltura = 50;
			}
			primeiraJogada = false;
			this.ponta = 1;
		} else {
			switch (this.ponta){
			case 1:
				pecaX = pecaEsquerdaX;
				pecaY = pecaEsquerdaY;
				if(pedra.isDouble()) {
					pecaY = pecaY - 25;
					pecaX = pecaEsquerdaX + 50;
					imagemPeca = new ImageIcon(getClass().getResource("/imagens/" + valorPeca + ".png"));
					pecaLargura = 50;
					pecaAltura = 100;
					pecaEsquerdaX = pecaEsquerdaX - 50;
					if(pedra.getPeca().equals("55")) {
						pecaCimaX = pecaX;
				    	pecaBaixoX = pecaX;
					}
				} else {
					if(this.disposPedras.getFirst().isClipA()){
						if(pedra.getLadoA()==this.disposPedras.getFirst().getLadoA()) {
							valorPeca = String.valueOf(pb) + String.valueOf(pa);
						} else {
							valorPeca = String.valueOf(pa) + String.valueOf(pb);
						}
					} else {
						if(pedra.getLadoA()==this.disposPedras.getFirst().getLadoB()) {
							valorPeca = String.valueOf(pb) + String.valueOf(pa);
						} else {
							valorPeca = String.valueOf(pa) + String.valueOf(pb);
						}
					}
					imagemPeca = new ImageIcon(getClass().getResource("/imagensd/" + valorPeca + "d.png"));
					pecaLargura = 100;
					pecaAltura = 50;
					pecaEsquerdaX = pecaEsquerdaX - 100;
				}
				break;
			case 2:
				pecaX = pecaDireitaX;
				pecaY = pecaDireitaY;
				if(pedra.isDouble()) {
					pecaY = pecaY - 25;
					imagemPeca = new ImageIcon(getClass().getResource("/imagens/" + valorPeca + ".png"));
					pecaLargura = 50;
					pecaAltura = 100;
					pecaDireitaX = pecaDireitaX + 50;
					if(pedra.getPeca().equals("55")) {
						pecaCimaX = pecaX;
				    	pecaBaixoX = pecaX;
					}
				} else {
					if(this.disposPedras.getLast().isClipB()) {
						if(pedra.getLadoA()==this.disposPedras.getLast().getLadoB()) {
							valorPeca = String.valueOf(pa) + String.valueOf(pb);
						} else {
							valorPeca = String.valueOf(pb) + String.valueOf(pa);
						}
					} else {
						if(this.disposPedras.getLast().isClipA()){
							if(pedra.getLadoA()==this.disposPedras.getLast().getLadoA()) {
								valorPeca = String.valueOf(pa) + String.valueOf(pb);
							} else {
								valorPeca = String.valueOf(pb) + String.valueOf(pa);
							}
						} else {
							if(pedra.getLadoA()==this.disposPedras.getLast().getLadoB()) {
								valorPeca = String.valueOf(pa) + String.valueOf(pb);
							} else {
								valorPeca = String.valueOf(pb) + String.valueOf(pa);
							}
						}
					}
					imagemPeca = new ImageIcon(getClass().getResource("/imagensd/" + valorPeca + "d.png"));
					pecaLargura = 100;
					pecaAltura = 50;
					pecaDireitaX = pecaDireitaX + 100;
				}
				break;
			case 3:
				pecaX = pecaCimaX;
				pecaY = pecaCimaY;
				if(pedra.isDouble()) {
					pecaX = pecaCimaX - 25;
					pecaY = pecaCimaY + 50;
					imagemPeca = new ImageIcon(getClass().getResource("/imagensd/" + valorPeca + "d.png"));
					pecaLargura = 100;
					pecaAltura = 50;
					pecaCimaY = pecaCimaY - 50;
				} else {
					if(this.ptaC.getLast().isClipA()){
						if(pedra.getLadoA()==this.ptaC.getLast().getLadoA()) {
							valorPeca = String.valueOf(pb) + String.valueOf(pa);
						} else {
							valorPeca = String.valueOf(pa) + String.valueOf(pb);
						}
					} else {
						if(pedra.getLadoA()==this.ptaC.getLast().getLadoB()) {
							valorPeca = String.valueOf(pb) + String.valueOf(pa);
						} else {
							valorPeca = String.valueOf(pa) + String.valueOf(pb);
						}
					}
					imagemPeca = new ImageIcon(getClass().getResource("/imagens/" + valorPeca + ".png"));
					pecaLargura = 50;
					pecaAltura = 100;
					pecaCimaY = pecaCimaY - 100;
				}
				break;
			case 4:
				pecaX = pecaBaixoX;
				pecaY = pecaBaixoY;
				if(pedra.isDouble()) {
					pecaX = pecaX - 25;
					imagemPeca = new ImageIcon(getClass().getResource("/imagensd/" + valorPeca + "d.png"));
					pecaLargura = 100;
					pecaAltura = 50;
					pecaBaixoY = pecaBaixoY + 50;
				} else {
					if(this.ptaD.getLast().isClipA()){
						if(pedra.getLadoA()==this.ptaD.getLast().getLadoA()) {
							valorPeca = String.valueOf(pa) + String.valueOf(pb);
						} else {
							valorPeca = String.valueOf(pb) + String.valueOf(pa);
						}
					} else {
						if(pedra.getLadoA()==this.ptaD.getLast().getLadoB()) {
							valorPeca = String.valueOf(pa) + String.valueOf(pb);
						} else {
							valorPeca = String.valueOf(pb) + String.valueOf(pa);
						}
					}
					imagemPeca = new ImageIcon(getClass().getResource("/imagens/" + valorPeca + ".png"));
					pecaLargura = 50;
					pecaAltura = 100;
					pecaBaixoY = pecaBaixoY + 100;
				}
				break;
			}
		}
		jLabelAtual = new JLabel();
		jLabelAtual.setBounds(new Rectangle(pecaX, pecaY, pecaLargura, pecaAltura));
		jLabelAtual.setIcon(imagemPeca);
		add(jLabelAtual);
		repaint();
	}

	@Override
	public void dropActionChanged(DropTargetDragEvent arg0) {
	}
	
	public void reverterDisposicao() {
    	remove(jLabelAtual);
    	switch (this.ponta){
		case 1:
			pecaEsquerdaX = pecaEsquerdaX + 100;
			break;
		case 2:
			pecaDireitaX = pecaDireitaX - 100;
			break;
		case 3:
			pecaCimaY = pecaCimaY + 100;
			break;
		case 4:
			pecaBaixoY = pecaBaixoY - 100;
			break;
		}
    }

	public void posicionarDouble5(Pedra pedra) {
		this.disposPedras.addFirst(pedra);
		this.ptaC.addFirst(pedra);
		this.ptaD.addFirst(pedra);
		posicionarPeca(pedra);
	}
	
}
